package cn.edu.gzhu.workOrderManagement.service.impl;

import cn.edu.gzhu.workOrderManagement.mapper.UserMapper;
import cn.edu.gzhu.workOrderManagement.mapper.OrganizationMapper;
import cn.edu.gzhu.workOrderManagement.pojo.dto.organization.OrganizationListDto;
import cn.edu.gzhu.workOrderManagement.pojo.dto.user.*;
import cn.edu.gzhu.workOrderManagement.pojo.entity.Organization;
import cn.edu.gzhu.workOrderManagement.pojo.entity.User;
import cn.edu.gzhu.workOrderManagement.pojo.vo.OrganizationListVo;
import cn.edu.gzhu.workOrderManagement.pojo.vo.UserLoginVo;
import cn.edu.gzhu.workOrderManagement.pojo.vo.UserVo;
import cn.edu.gzhu.workOrderManagement.properties.JwtProperties;
import cn.edu.gzhu.workOrderManagement.service.OrganizationService;
import cn.edu.gzhu.workOrderManagement.service.UserService;
import cn.edu.gzhu.workOrderManagement.util.JwtUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 普通用户接口实现类
 * 鉴权与授权写在拦截器中，仅有普通的增删查改
 * @author chen xi
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
    @Autowired
    OrganizationService organizationService;
    @Autowired
    OrganizationMapper organizationMapper;
    @Autowired
    JwtProperties jwtProperties;

    /**
     * 注册，插入成功返回1失败返回0,使用sha256加密密码
     * @param userRegisterDto 包含username password organization authority
     * @return 返回0则注册失败
     */
    @Override
    public Boolean saveUser(UserRegisterDto userRegisterDto) {
        //首先查看组织是否存在，不存在直接返回false

        Organization organization = organizationMapper.selectOne(new QueryWrapper<Organization>().eq("name", userRegisterDto.getOrganization()));

        //查看组织是否存在或启用
        if (organization==null|| !organization.getIsAvailable()) {
            return false;
        }
        //校验组织人数是否超过上线
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("organization", userRegisterDto.getOrganization());
        Integer sum = baseMapper.selectCount(queryWrapper);
        if (sum>=organization.getCapacity()) {
            return false;
        }
        //查看是否有相同用户名的用户
        IPage<UserVo> users = this.listByConditions(UserListDto.builder()
                .username(userRegisterDto.getUsername()).startPage(0).pageSize(10).build());
        long total = users.getTotal();
        if (total !=0) {
            return false;
        }
        //sha256摘要，转换密码，准备插入
        String password = userRegisterDto.getPassword();
        String passwordBySha256 = DigestUtil.sha256Hex(password);

        User user = new User();

        BeanUtils.copyProperties(userRegisterDto,user);

        user.setPassword(passwordBySha256);
        user.setIsAvailable(false);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());

        return this.save(user);
    }

    /**
     * 登入颁发jwt令牌，登入成功返回userVo中的用户数据以及JWT令牌，不成功返回空对象
     * @param userLoginDto 包含username password
     * @return
     */
    @Override
    public UserLoginVo getUserByUsernameAndPW(UserLoginDto userLoginDto) {
        // 1️⃣ 把密码转换为 SHA-256 摘要
        String passwordBySha256 = DigestUtil.sha256Hex(userLoginDto.getPassword());

        // 2️⃣ 构造查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, userLoginDto.getUsername())
                .eq(User::getPassword, passwordBySha256)
                .eq(User::getIsAvailable, true); // 只有启用的用户才能登录

        // 3️⃣ 查询用户
        User user = this.getOne(queryWrapper);
        if (user == null) {
            return null;
        }
        //查看组织是否启用，未启用不能登入
        QueryWrapper<Organization> organizationLambdaQueryWrapper =new QueryWrapper<>();
        organizationLambdaQueryWrapper.eq("name",user.getOrganization());
        Organization organization = organizationMapper.selectOne(organizationLambdaQueryWrapper);
        if (!organization.getIsAvailable()) {
            return null;
        }
        // 4️⃣ 构造返回对象 UserLoginVo
        UserLoginVo userLoginVo = new UserLoginVo();
        BeanUtils.copyProperties(user, userLoginVo);

        // 5️⃣ 生成 JWT 令牌
        HashMap<String, Object> claims = new HashMap<>();
        claims.put("username", user.getUsername());
        claims.put("authority", user.getAuthority().getRole());
        claims.put("organization", user.getOrganization());

        String jwt = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
        userLoginVo.setToken(jwt);

        return userLoginVo;
    }


    /**
     * 按条件查询组织中的用户
     * @param userListDto
     * @return
     */
    @Override
    public IPage<UserVo> listByConditions(UserListDto userListDto) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        // 条件构造
        if (StringUtils.isNotBlank(userListDto.getUsername())) {
            queryWrapper.like(User::getUsername, userListDto.getUsername());
        }
        if (userListDto.getIsAvailable() != null) {
            queryWrapper.eq(User::getIsAvailable, userListDto.getIsAvailable());
        }
        if (userListDto.getAuthority() != null) {
            queryWrapper.eq(User::getAuthority, userListDto.getAuthority());
        }
        if (StringUtils.isNotBlank(userListDto.getOrganization())) {
            queryWrapper.eq(User::getOrganization, userListDto.getOrganization());
        }

        // 分页查询
        Page<User> page = new Page<>(userListDto.getStartPage(), userListDto.getPageSize());
        IPage<User> userPage = this.page(page, queryWrapper);

        // 转换为 VO
        List<UserVo> voList = userPage.getRecords().stream()
                .map(user -> {
                    UserVo userVo = new UserVo();
                    BeanUtils.copyProperties(user, userVo);
                    return userVo;
                }).collect(Collectors.toList());

        IPage<UserVo> voPage = new Page<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
        voPage.setRecords(voList);
        return voPage;
    }
    /**
     * 修改用户属性
     * @param userUpdateDto
     * @return
     */
    @Override
    public Boolean updateUser(UserUpdateDto userUpdateDto) {
        User user = new User();
        BeanUtils.copyProperties(userUpdateDto,user);
        //如果需要更新密码，则把密码先用sha256摘要再更新
        if(user.getPassword()!=null){
            user.setPassword(DigestUtil.sha256Hex(user.getPassword()));
        }
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getUsername, user.getUsername());

        if (StringUtils.isNotBlank(user.getPassword())) {
            updateWrapper.set(User::getPassword, user.getPassword());
        }
        if (user.getAuthority()!=null) {
            updateWrapper.set(User::getAuthority, user.getAuthority());
        }
        if (StringUtils.isNotBlank(user.getOrganization())) {
            updateWrapper.set(User::getOrganization, user.getOrganization());
        }
        if (user.getIsAvailable() != null) {
            updateWrapper.set(User::getIsAvailable, user.getIsAvailable());
        }
        updateWrapper.set(User::getUpdateTime, LocalDateTime.now());
        return this.update(updateWrapper);

    }

    /**
     * 按用户名批量删除用户
     * @param userDeleteDto
     * @return
     */
    @Override
    public Boolean deleteUsersByUsernames(UserDeleteDto userDeleteDto) {
        List<String> usernames = userDeleteDto.getUsernames();

        return this.remove(new LambdaQueryWrapper<User>().in(User::getUsername, usernames));
    }

    /**
     * 根据组织名删除组织下所有用户
     *
     * @param organization
     * @return
     */
    @Override
    public Boolean deleteUsersByOrganization(String organization) {
        if (StringUtils.isBlank(organization)) {
            return false; // 组织名称为空，直接返回
        }

        // 执行删除
        return this.remove(new LambdaQueryWrapper<User>()
                .eq(User::getOrganization, organization));
    }


}
